
package com.hlkj.pay.app.merchant.ext.impl.alipayZft.ext;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import com.alipay.api.AlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.json.JSONWriter;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelRefundPayOrderContext;
import com.hlkj.pay.app.merchant.ext.impl.alipay.constant.AliPayExtConstant;
import com.hlkj.pay.app.merchant.ext.impl.alipay.dto.AlipayConfig;
import com.hlkj.pay.app.merchant.ext.impl.alipay.handler.AliPayCommonParamsHandle;
import com.hlkj.pay.app.merchant.ext.impl.alipayZft.AlipayZftScenePayOrderExtPt;
import com.hlkj.pay.app.merchant.ext.impl.alipayZft.dto.AliPayZftChannelParams;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.vo.order.req.PayOrderCommonParamReq;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 主扫统一下单
 * 
 * @author HlpayTeam
 * @date 2024/11/18 13:07
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = AliPayExtConstant.NATIVE_PAY)
public class AlipayZftNativePayOrderExtPt extends AlipayZftSceneCommonPayOrder implements AlipayZftScenePayOrderExtPt {

    private final AliPayCommonParamsHandle aliPayCommonParamsHandle;

    @Value("${hlkj.domain}")
    private String domain;

    @Override
    public void submitChannelPayOrder(ChannelPayOrderContext channelPayOrderContext) {
        // 判断商户类型
        MerchantAppChannelDO merchantAppChannelDO = channelPayOrderContext.getMerchantAppChannelDO();
        // 是否普通商户
        boolean common = aliPayCommonParamsHandle.commonMer(merchantAppChannelDO);
        // 普通商户
        if(common){
            channelPayOrderContext.setRemark("支付宝直付通不支持普通商户");
            channelPayOrderContext.setProcessStatus(false);
            return;
        }
        // 支付宝直付通配置信息
        CommonResult<AlipayConfig> alipayConfigCommonResult = aliPayCommonParamsHandle.alipayConfig(channelPayOrderContext.getProviderChannelConfigDO().getParamsConfig());
        if(!alipayConfigCommonResult.isSuccess()){
            channelPayOrderContext.setRemark(alipayConfigCommonResult.getMsg());
            channelPayOrderContext.setProcessStatus(false);
            return;
        }
        // 额外参数信息
        PayOrderCommonParamReq.Extra extra = channelPayOrderContext.getExtra();
        PayOrderDO payOrderDO = channelPayOrderContext.getPayOrderDO();
        try {
            // 服务商
            AliPayZftChannelParams aliPayChannelParams = JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), AliPayZftChannelParams.class);
            // 获取AlipayClient
            AlipayClient client = aliPayCommonParamsHandle.initClient(alipayConfigCommonResult.getData());
            // 响应参数
            AlipayTradeWapPayResponse response = null;
            // 请求参数封装
            AlipayTradeWapPayModel model = new AlipayTradeWapPayModel  ();
            model.setSubject(payOrderDO.getSubject());
            model.setTotalAmount(NumberUtil.roundStr(payOrderDO.getAmount().doubleValue(),2));
            model.setOutTradeNo(payOrderDO.getPayOrderNo());
            model.setTimeExpire(DateUtils.dateToString(payOrderDO.getExpiredTime(), DatePattern.NORM_DATETIME_PATTERN));
            model.setProductCode("QUICK_WAP_WAY");
            // 设置商户传入业务信息
            Map<String,String> businessParams = new HashMap<>();
            businessParams.put("mc_create_trade_ip",payOrderDO.getClientIp());
            model.setBusinessParams(JSONUtil.toJsonStr(businessParams));

            // 结算信息
            SettleInfo settleInfo = new SettleInfo();
            SettleDetailInfo settleDetailInfo = new SettleDetailInfo();
            settleDetailInfo.setTransInType("loginName");
            settleDetailInfo.setTransIn(aliPayChannelParams.getSettleNo());
            settleDetailInfo.setAmount(model.getTotalAmount());
            settleInfo.setSettleDetailInfos(CollUtil.newArrayList(settleDetailInfo));
            settleInfo.setSettlePeriodTime("1d");
            model.setSettleInfo(settleInfo);

            // 直付通商户
            SubMerchant subMerchant = new SubMerchant();
            subMerchant.setMerchantId(aliPayChannelParams.getSubMchId());
            subMerchant.setMerchantType("alipay");
            model.setSubMerchant(subMerchant);

            // 禁用渠道集合
            List<String> disablePayChannels = new ArrayList<>();
            // 禁用信用卡
            if(aliPayChannelParams.getDisCreditCard() != null && aliPayChannelParams.getDisCreditCard() == 1){
                disablePayChannels.add("creditCard");
                disablePayChannels.add("creditCardExpress");
                disablePayChannels.add("creditCardCartoon");
                disablePayChannels.add("credit_group");
            }
            // 禁用花呗
            if(aliPayChannelParams.getDisHb() != null && aliPayChannelParams.getDisHb() == 1){
                disablePayChannels.add("pcredit");
                disablePayChannels.add("pcreditpayInstallment");
            }else{
                // 花呗分期
                if(extra.getHbFqType() != null && extra.getHbFqFeeType() != null){
                    String hbfq = aliPayCommonParamsHandle.hbFqType(extra.getHbFqType());
                    String hbfqFee = aliPayCommonParamsHandle.hbFqFeeType(extra.getHbFqFeeType());
                    if(StrUtil.isNotEmpty(hbfq) && StrUtil.isNotEmpty(hbfqFee)){
                        ExtendParams extendParams = new ExtendParams();
                        extendParams.setHbFqNum(hbfq);
                        extendParams.setHbFqSellerPercent(hbfqFee);
                        model.setExtendParams(extendParams);
                    }
                }
            }
            if(CollUtil.isNotEmpty(disablePayChannels)){
                // 设置禁用渠道
                model.setDisablePayChannels(StrUtil.join(",",disablePayChannels));
            }
            //设置业务参数
            Map<String, Object> bizParams = JSONUtil.toBean((new JSONWriter()).write(model, true),Map.class);
            // B2B支付
            if(aliPayChannelParams.getB2bPay() != null && aliPayChannelParams.getB2bPay() == 1){
                Map<String,Object> extend_params = new HashMap<>();
                extend_params.put("paySolution","E_PAY");
                Map<String,Object> paySolutionScene = new HashMap<>();
                paySolutionScene.put("paySolutionScene","ENTERPRISE_PAY");
                extend_params.put("paySolutionConfig",JSONUtil.toJsonStr(paySolutionScene));
                // map合并
                Map<String,Object> old_extend_params  = MapUtil.get(bizParams,"extend_params",Map.class);
                if(MapUtil.isNotEmpty(old_extend_params)){
                    extend_params.putAll(old_extend_params);
                }
                bizParams.put("extend_params",extend_params);
            }

            // 构造请求参数以调用接口
            AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
            request.setNotifyUrl(channelPayOrderContext.getNotifyUrl());
            request.setReturnUrl(channelPayOrderContext.getRedirectUrl());
            request.setBizContent(JSONUtil.toJsonStr(bizParams));

            log.info("服务商支付宝直付通扫码支付请求参数:{}", JSONUtil.toJsonStr(bizParams));
            response = client.pageExecute(request,"GET");
            log.info("支付宝直付通扫码支付返回参数:{}", JSONUtil.toJsonStr(response));

            if (response.isSuccess()) {
                channelPayOrderContext.setPayDataType("pay_url");
                channelPayOrderContext.setPayInfo(response.getBody());
            }else{
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelPayOrderContext.setRemark(response.getSubMsg());
            }
        }catch (Exception e) {
            log.error("支付宝直付通扫码支付请求失败 message:{}", e);
            channelPayOrderContext.setRemark("支付宝直付通扫码支付请求失败,失败信息" + e.getMessage());
            channelPayOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }

    @Override
    public void queryChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonQueryChannelPayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void closeChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonCloseChannelPayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void queryChannelClosePayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonQueryChannelClosePayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void refundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        commonRefundChannelPayOrder(channelRefundPayOrderContext);
    }

    @Override
    public void queryRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        commonQueryRefundChannelPayOrder(channelRefundPayOrderContext);
    }

    @Override
    public boolean refundApply(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        return true;
    }

    @Override
    public CommonResult<String> channelOrderCode(ChannelPayOrderContext channelPayOrderContext) {
        return CommonResult.success();
    }
}
